<template>
  <Cell title="我的收益" is-link :to="{ path: '/share/profit' }" :value-class="incomeAmount > 0 ? 'rise' : (incomeAmount < 0 ? 'fall' : '')">
    <b>
      {{ originalAmount.toFixed(2) }}
      <sup>{{ ((totalAmount - originalAmount) / originalAmount * 100).toFixed(2) }}%</sup>
    </b>
    <b>{{ totalAmount }}</b>
    <b>{{ incomeAmount.toFixed(2) }}</b>
  </Cell>

  <CellGroup style="margin-top: 5px">
    <SwipeCell v-for="item of shares">
      <Cell :title="item.Name" is-link :to="{ path: `/share/${item.Code}/details`, query: { title: item.Name } }">
        <component :is="getCurrent(item)" />
        <component :is="getMyProfit(item)" />
      </Cell>
      <template #left>
        <Button square text="买入" icon="gold-coin-o" type="primary" @click="saleIn(item)" />
      </template>
      <template v-if="item.PurchaseOn" #right>
        <Button square text="卖出" icon="after-sale" type="danger" @click="saleOut(item)" />
      </template>
    </SwipeCell>
  </CellGroup>

  <Popup v-model:show="showPicker" position="bottom" style="width: 100%; bottom: 0">
    <Form @submit="saveShare">
      <CellGroup inset>
        <Field label="股票代号" v-model="info.Code" :disabled="true" />
        <Field label="股票名称" v-model="info.Name" :disabled="true" />
        <Field label="关注日期" v-model="info.CreatedOn" :disabled="true" />
        <Field label="购买日期" v-model="info.PurchaseOn" readonly>
          <template #button>
            <div class="date-buttons">
              <Button round size="small" type="primary" @click="showDatePicker = true">选择</Button>
              <Button round size="small" type="danger" @click="info.PurchaseOn = ''">清除</Button>
            </div>
          </template>
        </Field>
        <Field label="购买价格" type="number" v-model="info.PurchasePrice" />
        <Field label="购买数量" type="digit" v-model="info.PurchaseQuantity" />
      </CellGroup>
      <div class="buttons">
        <Button round type="primary" size="small" native-type="submit">保存</Button>
        <Button round type="warning" size="small" @click="showPicker = false">取消</Button>
      </div>
    </Form>
  </Popup>

  <Calendar ref="calendar" :min-date="minDate" v-model:show="showDatePicker" @confirm="confirmDate" />
</template>
<script setup>
import dayjs from 'dayjs';
import { useStore } from 'vuex';
import { h, inject, ref, reactive, markRaw, onMounted, onUnmounted, defineAsyncComponent } from 'vue';
import { CellGroup, Cell, SwipeCell, Toast, Button, Popup, Form, Field, Calendar } from 'vant';

import helpers from '@/libs/helpers';
import refresher from '@/libs/autoRefreshShares';

const $store = useStore();
const $http = inject('$http');

const shares = ref([]);
const calendar = ref();
const minDate = new Date(2021, 0, 1);

const info = reactive({});
const originalAmount = ref(0);
const totalAmount = ref(0);
const incomeAmount = ref(0);
const showPicker = ref(false);
const showDatePicker = ref(false);

const countDown = ref(5);
const countDownVisible = ref(false);

function loadShares () {
  $http.get('/api/shares/list', { hideTip: true }).then(res => {
    shares.value = res.datas;
    totalAmount.value = 0;
    incomeAmount.value = 0;
    originalAmount.value = 0;

    (shares.value || []).forEach(s => {
      let beginPrice = s.PurchasePrice;
      let currentPrice = s.CurrentPrice;

      totalAmount.value += currentPrice * s.PurchaseQuantity;
      originalAmount.value += beginPrice * s.PurchaseQuantity;
      incomeAmount.value += (currentPrice - beginPrice) * s.PurchaseQuantity;
    });
  });
}

function getCurrent (record) {
  let beginPrice = record.BeginPrice;
  let yesterdayPrice = record.YesterdayPrice;
  let currentPrice = record.CurrentPrice;

  let rate = (((currentPrice - yesterdayPrice) / yesterdayPrice) * 100).toFixed(2);
  let totalRate = (((currentPrice - beginPrice) / beginPrice) * 100).toFixed(2);

  return h('div', { class: 'complexs' }, [
    h('span', { style: { color: getShareColor(totalRate, 0) } }, `${beginPrice} / ${totalRate}%`),
    h('span', { style: { color: getShareColor(currentPrice, yesterdayPrice) } }, currentPrice),
    h(
      'span',
      {
        style: {
          color: getShareColor(currentPrice, yesterdayPrice)
        }
      },
      rate == 'NaN' ? 'N/A' : rate + '%'
    )
  ]);
}

function getMyProfit (record) {
  if ((record.PurchaseQuantity || 0) <= 0) {
    return h('span', '');
  }

  let beginPrice = record.PurchasePrice;
  let currentPrice = record.CurrentPrice;
  let rate = (((currentPrice - beginPrice) / beginPrice) * 100).toFixed(2);
  let amount = (record.PurchaseQuantity * currentPrice).toFixed(2);

  let htmlAttrs = {
    style: {
      color: getShareColor(currentPrice, beginPrice)
    }
  };

  return h('div', { class: 'complexs' }, [
    h('span', htmlAttrs, amount),
    h('span', htmlAttrs, ((currentPrice - beginPrice) * record.PurchaseQuantity).toFixed(2)),
    h('span', htmlAttrs, rate + '%')
  ]);
}

function getShareColor (currentPrice, yesterdayPrice) {
  let color = '#909499';

  if (currentPrice > yesterdayPrice) {
    color = '#ed4014';
  } else if (currentPrice < yesterdayPrice) {
    color = '#19be6b';
  }

  return color;
}

function saleIn (item) {
  showPicker.value = true;

  helpers.fillDatas(info, markRaw(item));
  info.PurchaseOn = info.PurchaseOn ? helpers.dateFormat(info.PurchaseOn) : '';
}

function saleOut (item) {
  showPicker.value = true;

  helpers.fillDatas(info, markRaw(item));
  info.PurchaseOn = info.PurchaseOn ? helpers.dateFormat(info.PurchaseOn) : '';
}

function confirmDate (value) {
  info.PurchaseOn = helpers.dateFormat(value);

  showDatePicker.value = false;
}

function saveShare () {
  let rawInfo = JSON.parse(JSON.stringify(markRaw(info)));

  rawInfo.PurchasePrice = rawInfo.PurchasePrice || null;
  rawInfo.PurchaseQuantity = rawInfo.PurchaseQuantity || null;
  rawInfo.CreatedOn = dayjs(rawInfo.CreatedOn).format('YYYY-MM-DD HH:mm:ss');
  rawInfo.PurchaseOn = rawInfo.PurchaseOn ? dayjs(rawInfo.PurchaseOn).format('YYYY-MM-DD HH:mm:ss') : null;

  if (!rawInfo.Code) {
    Toast.fail('股票编号不能为空！');

    return;
  }

  if (!rawInfo.Name) {
    Toast.fail('股票名称不能为空！');

    return;
  }

  if (rawInfo.Code.indexOf('00') == 0 || rawInfo.Code.indexOf('200') == 0 || rawInfo.Code.indexOf('30') == 0) {
    rawInfo.Code = 'sz' + rawInfo.Code;
  } else if (rawInfo.Code.indexOf('60') == 0 || rawInfo.Code.indexOf('900') == 0) {
    rawInfo.Code = 'sh' + rawInfo.Code;
  }

  $http.post('/api/shares/save', rawInfo).then(res => {
    if (res.success) {
      Toast.success('保存成功！');
      showPicker.value = false;

      loadShares();
    } else {
      Toast.fail('出现错误，错误详情：' + res.message);
    }
  });
}

onMounted(() => {
  $store.commit('navigateBack', { path: '/' });
  $store.commit('navigateTitle', `股票列表@${helpers.dateFormat(new Date())}`);

  loadShares();

  refresher.start({
    step ({ visible, number }) {
      countDown.value = number;
      countDownVisible.value = visible;
    },
    done () {
      loadShares();
    }
  });
});

onUnmounted(() => {
  refresher.stop();
});
</script>

<style lang="less" scoped>
:deep(.van-swipe-cell__right) {
  right: -1px;
}

.van-cell {
  align-items: center;
  padding-left: 10px;
  padding-right: 10px;

  > :deep(.van-cell__title) {
    font-weight: bold;
    flex: none;
    width: 70px;
    white-space: nowrap;
  }

  > :deep(.van-cell__value) {
    display: flex;
    flex: 2;
    width: 100%;
    line-height: 30px;
    flex-flow: row wrap;
    color: #909499;
    align-items: center;
    justify-content: space-between;

    &.rise {
      color: rgb(237, 64, 20);
    }

    &.fall {
      color: rgb(25, 190, 107);
    }

    >b {
      text-align: left;
      font-size: 13px;
      font-weight: bolder;

      >sup {
        position: relative;
        left: -40px;
        top: -10px;
      }

      &:nth-of-type(2n) {
        text-align: center;
      }

      &:last-of-type {
        text-align: right;
      }
    }

    >.complexs {
      width: 100%;
      display: flex;
      flex-flow: row nowrap;
      font-size: 13px;
      align-items: center;
      justify-content: space-between;
      white-space: nowrap;
      margin: 0;
      padding: 0;
      line-height: 1.3;

      >span {
        font-style: normal;
        text-align: left;
        font-weight: bold;

        &:first-of-type {
          width: 140px;
          display: inline-block;
        }

        &:not(:first-of-type) {
          flex: 0 0 calc((100% - 110px) / 2);
        }

        &:last-of-type {
          text-align: right;
        }
      }
    }
  }

  > :deep(.van-cell__right-icon) {
    width: 20px;
  }
}

.buttons {
  display: flex;
  margin-top: 10px;
  align-items: center;
  flex-flow: row nowrap;
  justify-content: center;

  >.van-button {
    flex: 0 0 30%;
    margin-left: 10px;

    &:first-of-type {
      margin-left: 0;
    }
  }
}

.date-buttons {
  display: flex;
  flex-flow: row nowrap;

  >.van-button {
    border-radius: 8px;

    &:first-of-type {
      border-top-right-radius: 0;
      border-bottom-right-radius: 0;
    }

    &:not(:first-of-type) {
      border-top-left-radius: 0;
      border-bottom-left-radius: 0;
    }
  }
}
</style>
